package game;

import heroes.Hero;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.ArrayList;

import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JToggleButton;
import javax.swing.border.Border;

import cards.Card;
import cards.Equipment;
import cards.Weapon;
public class LowerEquipPanel extends JPanel implements CardContainer {
	LowerPanel myLowerPanel;
	public static int LOWER_PANEL_EQUIP_WIDTH;
	public static int LOWER_PANEL_EQUIP_HEIGHT;
	public static int BUTTON_MOVE_LENGTH;

	public static void initPreferredSize() {
		LOWER_PANEL_EQUIP_WIDTH = BattleField.BATTLE_FIELD_WIDTH / 4;
		LOWER_PANEL_EQUIP_HEIGHT = LowerPanel.LOWER_PANEL_HEIGHT;
		BUTTON_MOVE_LENGTH = LOWER_PANEL_EQUIP_WIDTH / 10;
	}

	Hero myHero;
	// this will be useful for GuanShi
	ArrayList<Card> equipCards = new ArrayList<Card>();
	// TODO build link
	ArrayList<EquipButton> equipButtons = new ArrayList<LowerEquipPanel.EquipButton>();
	EquipButton weaponButton;
	EquipButton armorButton;
	EquipButton plusHorseButton;
	EquipButton minusHorseButton;

	// when one button's corresponding equipment is clickable,
	// use a boolean to indicate it
	@Override
	public void addCard(Card card) {
		equipCards.add(card);
		card.linkCardContainer(this);
	}

	@Override
	public void removeCard(Card toBremoved) {
		toBremoved.delink();
		equipCards.remove(toBremoved);
		((Equipment)toBremoved).getLinkedButton().removeEquip();
	}

	@Override
	public void clickUpdate(Card newUpdate) throws InterruptedException {
		myLowerPanel.clickUpdate(newUpdate);
	}

	//
	// public void setRequiredNum(int n) {
	// requiredNum = n;
	// }

	// public void requiredNumReached() {
	// for (Card everyone : equipCards) {
	// everyone.clickable = false;
	// }
	// for (Card everyone : clickedEquips) {
	// everyone.clickable = true;
	// }
	// ready = true;
	// }

	public void cancelAllClicked() {
		for (EquipButton every : equipButtons) {
			if (every.isClicked()) {
				// every.moveButtonLeft();
				every.setClicked(false);
			}
		}
	}

	public void highlightOneEquip(int toB, boolean highlight) {
		switch (toB) {
		case 1:
			weaponButton.setClickable(highlight);
			break;
		case 2:
			armorButton.setClickable(highlight);
			break;
		case 3:
			plusHorseButton.setClickable(highlight);
			break;
		case 4:
			minusHorseButton.setClickable(highlight);
			break;
		}
	}

	public void putOffHighLight() {

	}

	public LowerEquipPanel(LowerPanel toB) {
		super();
		myLowerPanel = toB;
		setLayout(new GridLayout(0, 1, 0, 0));
		setPreferredSize(new Dimension(LOWER_PANEL_EQUIP_WIDTH,
				LOWER_PANEL_EQUIP_HEIGHT));
		Border lineBorder = BorderFactory.createLineBorder(Color.black, 2);
		setBorder(lineBorder);
		weaponButton = new EquipButton();
		armorButton = new EquipButton();
		plusHorseButton = new EquipButton();
		minusHorseButton = new EquipButton();
		equipButtons.add(weaponButton);
		equipButtons.add(armorButton);
		equipButtons.add(plusHorseButton);
		equipButtons.add(minusHorseButton);
		add(weaponButton);
		add(armorButton);
		add(plusHorseButton);
		add(minusHorseButton);
		// Border thinBorder = BorderFactory.createLineBorder(Color.gray, 1);
		// myHero = toB.myHero;
	}

	public void linkToHero() {
		myHero = myLowerPanel.myHero;
	}

	public void playReadyState() {
		if (myHero.canAttack() && myHero.weaponEquipped
				&& myHero.weapon.getName() == "ZhangBa") {
			weaponButton.setClickable(true);
		}
		// TODO check which equipment is clickable
	}

	// @deprecated, see LowerPanel.pandinChangeReadyState().
	// use equip cards to change pandin
	// public void pandinChangeReadyState() {
	// // highlight all four equipments
	// if (myHero.canUseCardToChangePandin(this.weaponButton.linkedEquip)) {
	// highlightOneEquip(1, true);
	// }
	// if (myHero.canUseCardToChangePandin(this.armorButton.linkedEquip)) {
	// highlightOneEquip(2, true);
	// }
	// if (myHero.canUseCardToChangePandin(this.plusHorseButton.linkedEquip)) {
	// highlightOneEquip(3, true);
	// }
	// if (myHero.canUseCardToChangePandin(this.minusHorseButton.linkedEquip)) {
	// highlightOneEquip(4, true);
	// }
	// }

	// @deprecated
	// public void notifyLowerPanel() {
	// myLowerPanel.checkReady();
	// }

	public class EquipButton extends JPanel implements MouseListener {
		private boolean clickable = false;
		private boolean clicked = false;

		/**
		 * @return the clickable
		 */
		public boolean isClickable() {
			return clickable;
		}

		/**
		 * @return the clicked
		 */
		public boolean isClicked() {
			return clicked;
		}

		/**
		 * @param clickable
		 *            the clickable to set
		 */
		public void setClickable(boolean clickable) {
			this.clickable = clickable;
			resetBorder();
			revalidate();
			repaint();
		}

		/**
		 * @param clicked
		 *            the clicked to set
		 */
		public void setClicked(boolean clicked) {
			this.clicked = clicked;
			resetBorder();
			revalidate();
			repaint();
		}

		private void resetBorder() {
			if (clickable) {
				setBorder(clickableBorder);
			}
			if (clicked) {
				setBorder(clickedBorder);
			}
			if (!clickable) {
				setBorder(normalBorder);
			}
		}
		Border normalBorder = BorderFactory.createLineBorder(Color.white);
		Border clickableBorder = BorderFactory.createRaisedBevelBorder();
		Border clickedBorder = BorderFactory.createLoweredBevelBorder();

		// TODO, maybe i can make use of JCheckBox.setSelected()
		// and also, isSelected.
//		@Override
//		public void paintComponent(Graphics g) {
//			// Color origin = g.getColor();
//			// if (linkedEquip.getColor() <= 2) {
//			// g.setColor(Color.RED);
//			// } else {
//			// g.setColor(Color.BLACK);
//			// }
//			// super.paint(g);
//			// g.setColor(origin);
//		}

		Card linkedEquip;
		private JLabel colorNumber;
		private JLabel equipName;

		public void addEquip(Card toB) {
			// equipCards.add(toB);
			LowerEquipPanel.this.addCard(toB);
			linkedEquip = toB;
			((Equipment)toB).setLinkedButton(this);
			colorNumber = toB.getColorNumber();
			add(colorNumber);
			equipName = new JLabel(toB.getName());
			add(equipName);
			revalidate();
			repaint();
		}

		public void removeEquip() {
			LowerEquipPanel.this.remove(linkedEquip);
			((Equipment)linkedEquip).setLinkedButton(null);
			linkedEquip = null;
			remove(colorNumber);
			colorNumber = null;
			remove(equipName);
			equipName = null;
			setClickable(false);
			setClicked(false);
			revalidate();
			repaint();
		}

		// this one is called whenever the equip is changed or removed
		// public void setText() {
		// String toB = "";
		// if (linkedEquip != null) {
		// toB += linkedEquip.getName();
		// switch (linkedEquip.getColor()) {
		// case 1:
		// toB += " ♥ ";
		// break;
		// case 2:
		// toB += " ♦ ";
		// break;
		// case 3:
		// toB += " ♠ ";
		// break;
		// case 4:
		// toB += " ♣ ";
		// break;
		// }
		// toB += linkedEquip.getNumber();
		// }
		// super.setText(toB);
		// }

		/*
		 * (non-Javadoc)
		 * 
		 * @see javax.swing.AbstractButton#paintBorder(java.awt.Graphics)
		 */
		// @Override
		// protected void paintBorder(Graphics g) {
		// // Color origin = g.getColor();
		// // if (highlighted) {
		// // g.setColor(Color.CYAN);
		// // }
		// // super.paintBorder(g);
		// // g.setColor(origin);
		// }

		public EquipButton() {
			setPreferredSize(new Dimension(LOWER_PANEL_EQUIP_WIDTH,
					LOWER_PANEL_EQUIP_HEIGHT / 4));
			resetBorder();
			// addActionListener(new ActionListener() {
			//
			// @Override
			// public void actionPerformed(ActionEvent arg0) {
			//
			// // if (highlighted) {
			// // if (!clicked) {
			// // clicked = true;
			// // moveButtonRight();
			// // try {
			// // clickUpdate(linkedEquip);
			// // } catch (InterruptedException e) {
			// // e.printStackTrace();
			// // }
			// // } else {
			// // clicked = false;
			// // moveButtonLeft();
			// // try {
			// // clickUpdate(linkedEquip);
			// // } catch (InterruptedException e) {
			// // e.printStackTrace();
			// // }
			// // }
			// // }
			// }
			//
			// });
		}

		// TODO , not used for now, some visual feature, might implement later.
		// public void moveButtonRight() {
		// for (int m = 0; m < BUTTON_MOVE_LENGTH; m++) {
		// setLocation(getLocation().x + 1, getLocation().y);
		// }
		// }
		//
		// public void moveButtonLeft() {
		// for (int m = 0; m < BUTTON_MOVE_LENGTH; m++) {
		// setLocation(getLocation().x - 1, getLocation().y);
		// }
		// }

		@Override
		public void mouseClicked(MouseEvent e) {
			if (clickable) {
				setClicked(!isClicked());
				linkedEquip.setClicked(isClicked());
				try {
					clickUpdate(linkedEquip);
				} catch (InterruptedException e1) {
					e1.printStackTrace();
				}
			}
		}

		@Override
		public void mouseEntered(MouseEvent e) {
			// TODO Auto-generated method stub

		}

		@Override
		public void mouseExited(MouseEvent e) {
			// TODO Auto-generated method stub
		}

		@Override
		public void mousePressed(MouseEvent e) {

		}

		@Override
		public void mouseReleased(MouseEvent e) {

		}
	}

}